Releases: livestorejs/livestore
v0.3.0
New features
-
New sync implementation (based on git-like push/pull semantics)
- See Syncing docs page for more details
sync-cf
backend: More reliable websocket connection handling- Configurable sync semantics when app starts (either skip initial sync or block with timeout)
-
New: Node adapter
@livestore/adapter-node
(experimental)- Note: Currently uses the
@livestore/sqlite-wasm
build but the plan is to move to a native SQLite build in the future to improve performance and reduce bundle size. - Still lacks a few devtools-related flows (e.g. graceful import/reset)
- Note: Currently uses the
-
New:
@livestore/sync-electric
backend (experimental)- See docs page for more details
-
New:
@livestore/adapter-expo
now supports syncing (requires Expo 53 or later):const adapter = makePersistedAdapter({ sync: { backend: makeCfSync({ url: `https://...` }) }, })
-
New: Solid integration
@livestore/solid
(experimental)- Still very early stage and probably lacks some features. Feedback wanted!
- Thank you to @kulshekhar for the initial implementation! (See PR #225)
- There are is still a lot of work to be done - contributions welcome!
Breaking changes
-
Breaking: Renamed adapter packages:
@livestore/web
now is@livestore/adapter-web
@livestore/expo
now is@livestore/adapter-expo
-
Breaking: Removed
@livestore/db-schema
package and moved to@livestore/common/schema
-
Breaking: Renamed
store.mutate
tostore.commit
- Reason: Make it more clear that committing mutations is also syncing them across other clients
-
Breaking: Adjusted schema API
- The new API aims to separate the schema into state and events
- Mutations are now split up into event definitions and materializer functions
Before:
// mutations.ts import { Schema, defineMutation } from '@livestore/livestore' // Mutations are now split up into event definitions and materializer functions export const todoCreated = defineMutation('todoCreated', Schema.Struct({ id: DbSchema.text(), text: DbSchema.text(), }), sql`INSERT INTO todos (id, text) VALUES (${id}, ${text})`, ) // schema.ts import { DbSchema, makeSchema } from '@livestore/livestore' import * as mutations from './mutations.js' const todos = DbSchema.table('todos', { id: DbSchema.text({ primaryKey: true }), text: DbSchema.text(), }) const uiState = DbSchema.table('uiState', { id: DbSchema.text({ primaryKey: true }), newTodoText: DbSchema.text(), filter: DbSchema.text({ }), }, { derivedMutations: { clientOnly: true } }) const tables = { todos, uiState } const schema = makeSchema({ tables, mutations })
After:
// events.ts import { Events, Schema } from '@livestore/livestore' export const todoCreated = Events.synced({ name: 'todoCreated', schema: Schema.Struct({ id: Schema.String, text: Schema.String, }), }) // schema.ts import { State, Schema, makeSchema } from '@livestore/livestore' import * as events from './events.js' const todos = State.SQLite.table({ name: 'todos', columns: { id: State.SQLite.text({ primaryKey: true }), text: State.SQLite.text(), } }) // tables with `deriveMutations` are now called `clientDocuments` const uiState = State.SQLite.clientDocument({ name: 'uiState', schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.String, }), }) const tables = { todos, uiState } // Materalizers let you materialize events into the state const materializers = State.SQLite.materializers(events, { 'v1.TodoCreated': ({ id, text }) => todos.insert({ id, text }), }) // Currently SQLite is the only supported state implementation but there might be more in the future (e.g. pure in-memory JS, DuckDB, ...) const state = State.SQLite.makeState({ tables, materializers }) // Schema is now more clearly separated into state and events const schema = makeSchema({ state, events })
-
Breaking
@livestore/react
: RemoveduseScopedQuery
in favour ofuseQuery
. Migration example:// before const query$ = useScopedQuery(() => queryDb(tables.issues.query.where({ id: issueId }).first()), ['issue', issueId]) // after const query$ = useQuery(queryDb(tables.issues.query.where({ id: issueId }).first(), { deps: `issue-${issueId}` }))
-
Breaking
@livestore/adapter-web
: RenamedmakeAdapter
tomakePersistedAdapter
-
Breaking
@livestore/adapter-expo
: RenamedmakeAdapter
tomakePersistedAdapter
-
Breaking: Renamed
localOnly
toclientOnly
in table/mutation definitions. -
Breaking: Renamed
makeBackend
tobackend
in sync options. -
Breaking
@livestore/react
:useClientDocument
now only works with for tables with client-only derived mutations. -
Breaking: Instead of calling
query$.run()
/query$.runAndDestroy()
, please usestore.query(query$)
instead. -
Breaking: Removed
store.__execute
fromStore
. -
Breaking: Removed
globalReactivityGraph
and explicit passing ofreactivityGraph
to queries. -
Breaking: Removed
persisted
option fromstore.commit
. This will be superceded by eventlog compaction in the future. -
Breaking: The new syncing implementation required some changes to the storage format. The
liveStoreStorageFormatVersion
has been bumped to3
which will create new database files. -
Breaking: Moved
queryGraphQL
to@livestore/graphql
and thus removinggraphql
from peer dependencies of@livestore/livestore
. -
Moved dev helper methods from e.g.
store.__devDownloadDb()
tostore._dev.downloadDb()
-
Breaking
@livestore/sync-cf
: RenamedmakeWsSync
tomakeCfSync
Notable improvements & fixes
-
Added support for write queries in the query builder
table.query.insert({ id: '123', name: 'Alice' }) table.query.insert({ id: '123', name: 'Alice' }).onConflict('id', 'ignore') table.query.insert({ id: '123', name: 'Alice' }).returning('id') table.query.update({ name: 'Bob' }).where({ id: '123' }) table.query.delete().where({ id: '123' })
-
Introduced
@livestore/peer-deps
package to simplify dependency management for Livestore packages if you don't want to manually install all the peer dependencies yourself. -
Improved documentation (still a lot of work to do here)
-
Shows a browser dialog when trying to close a tab/window with unsaved changes
-
The SQLite leader database now uses the WAL mode to improve performance and reliability. (Thanks @IGassmann for the contribution #259.)
-
Improve Otel tracing integration
-
Fix: The query builder now correctly handles
IN
andNOT IN
where operations -
Fix: LiveStore crashes when using reserved keywords as a column name (
from
) #245
Devtools
- Changed devtools path from
/_devtools.html
to/_livestore
- General connection stability improvements
- Improved sync view:
- See sync heads in real-time
- Connect/disconnect button
- Improved eventlog view:
- Client-only mutations are now highlighted
- Added
clientId
/sessionId
columns
- Grouped slow queries and live queries under new queries tab
- Added SQLite query playground
- Fix: Data browser now more clearly highlights selected table #239
Examples
- Reworked the Linearlite React example. (Thanks @lukaswiesehan for the contribution #248.)
- Adjusted mutation names to use past-tense
- Added Otel to
todomvc
andtodomvc-sync-cf
example
Internal changes
- Embraced git-style push/pull semantics to sync mutations across the system
- Added node syncing integration tests
- Got rid of the coordinator abstraction in favour of a clear separation between leader and client sessions
- Renamed from
EventId.local
toEventSequenceNumber.client
- Added
@livestore/sqlite-wasm
package which wraps@livestore/wa-sqlite
and exposes web and Node.js compatible VFS implementations - New devtools protocol via webmesh
- Should improve reliability of devtools connection (particularly during app reloads)
- Large refactoring to share more code between adapters
- Renamed
SynchronousDatabase
toSqliteDb
- Upgrade to TypeScript 5.8
- Upgraded dependencies
- Now supports React 19
effect
(needs to be 3.15.2 or higher)@livestore/wa-sqlite
(needs to be 1.0.5-dev.2)
v0.3.0-dev.54
Release 0.3.0-dev.54
including Chrome Extension
v0.3.0-dev.53
Release 0.3.0-dev.53
including Chrome Extension
v0.3.0-dev.52
Release 0.3.0-dev.52
including Chrome Extension
v0.3.0-dev.51
Release 0.3.0-dev.51
including Chrome Extension
v0.3.0-dev.50
Release 0.3.0-dev.50
including Chrome Extension
v0.3.0-dev.49
Release 0.3.0-dev.49
including Chrome Extension
v0.3.0-dev.48
Release 0.3.0-dev.48
including Chrome Extension
v0.3.0-dev.47
Release 0.3.0-dev.47
including Chrome Extension
v0.3.0-dev.46
Release 0.3.0-dev.46
including Chrome Extension